{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2024-11-12T06:38:52.576975Z",
     "start_time": "2024-11-12T06:38:52.545081Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sqlite\n",
      "['Album', 'Artist', 'Customer', 'Employee', 'Genre', 'Invoice', 'InvoiceLine', 'MediaType', 'Playlist', 'PlaylistTrack', 'Track']\n"
     ]
    },
    {
     "data": {
      "text/plain": "\"[(1, 'AC/DC'), (2, 'Accept'), (3, 'Aerosmith'), (4, 'Alanis Morissette'), (5, 'Alice In Chains'), (6, 'Antônio Carlos Jobim'), (7, 'Apocalyptica'), (8, 'Audioslave'), (9, 'BackBeat'), (10, 'Billy Cobham')]\""
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_community.utilities import SQLDatabase\n",
    "db = SQLDatabase.from_uri(\"sqlite:///Chinook.db\")\n",
    "print(db.dialect)\n",
    "print(db.get_usable_table_names())\n",
    "db.run(\"select * from artist limit 10\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [],
   "source": [
    "from typing import Any\n",
    "\n",
    "from langchain_core.messages import ToolMessage\n",
    "from langchain_core.runnables import RunnableLambda, RunnableWithFallbacks\n",
    "from langgraph.prebuilt import ToolNode\n",
    "\n",
    "\n",
    "def create_tool_node_with_fallback(tools: list) -> RunnableWithFallbacks[Any, dict]:\n",
    "    \"\"\"\n",
    "    Create a ToolNode with a fallback to handle errors and surface them to the agent.\n",
    "    创建一个带有回退的ToolNode来处理错误并将它们显示给代理。\n",
    "    \"\"\"\n",
    "    return ToolNode(tools).with_fallbacks(\n",
    "        [RunnableLambda(handle_tool_error)], exception_key=\"error\"\n",
    "    )\n",
    "\n",
    "\n",
    "def handle_tool_error(state) -> dict:\n",
    "    error = state.get(\"error\")\n",
    "    tool_calls = state[\"messages\"][-1].tool_calls\n",
    "    return {\n",
    "        \"messages\": [\n",
    "            ToolMessage(\n",
    "                content=f\"Error: {repr(error)}\\n please fix your mistakes.\",\n",
    "                tool_call_id=tc[\"id\"],\n",
    "            )\n",
    "            for tc in tool_calls\n",
    "        ]\n",
    "    }"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-12T06:38:56.039115Z",
     "start_time": "2024-11-12T06:38:56.026159Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\n",
      "\n",
      "CREATE TABLE \"Artist\" (\n",
      "\t\"ArtistId\" INTEGER NOT NULL, \n",
      "\t\"Name\" NVARCHAR(120), \n",
      "\tPRIMARY KEY (\"ArtistId\")\n",
      ")\n",
      "\n",
      "/*\n",
      "3 rows from Artist table:\n",
      "ArtistId\tName\n",
      "1\tAC/DC\n",
      "2\tAccept\n",
      "3\tAerosmith\n",
      "*/\n"
     ]
    }
   ],
   "source": [
    "from get_ollama import GetOllama\n",
    "from langchain_community.agent_toolkits import SQLDatabaseToolkit\n",
    "llm = GetOllama(model_name=\"qwen2.5:14b\", model_type=1, temperature=0)()\n",
    "toolkit = SQLDatabaseToolkit(db=db, llm=llm)\n",
    "tools = toolkit.get_tools()\n",
    "list_tables_tool = next(tool for tool in tools if tool.name == \"sql_db_list_tables\")\n",
    "get_schema_tool = next(tool for tool in tools if tool.name == \"sql_db_schema\")\n",
    "print(list_tables_tool.invoke(\"\"))\n",
    "print(get_schema_tool.invoke(\"Artist\"))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-12T06:41:51.880206Z",
     "start_time": "2024-11-12T06:41:51.354318Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(1, 'AC/DC'), (2, 'Accept'), (3, 'Aerosmith'), (4, 'Alanis Morissette'), (5, 'Alice In Chains'), (6, 'Antônio Carlos Jobim'), (7, 'Apocalyptica'), (8, 'Audioslave'), (9, 'BackBeat'), (10, 'Billy Cobham')]\n"
     ]
    }
   ],
   "source": [
    "from langchain_core.tools import tool\n",
    "\n",
    "\n",
    "@tool\n",
    "def db_query_tool(query: str) -> str:\n",
    "    \"\"\"\n",
    "    Execute a SQL query against the database and get back the result.\n",
    "    If the query is not correct, an error message will be returned.\n",
    "    If an error is returned, rewrite the query, check the query, and try again.\n",
    "    \"\"\"\n",
    "    result = db.run_no_throw(query)\n",
    "    if not result:\n",
    "        return \"Error: Query failed. Please rewrite your query and try again.\"\n",
    "    return result\n",
    "\n",
    "\n",
    "print(db_query_tool.invoke(\"SELECT * FROM Artist LIMIT 10;\"))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-12T06:41:57.191203Z",
     "start_time": "2024-11-12T06:41:57.170273Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "data": {
      "text/plain": "AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'qwen2.5:14b', 'created_at': '2024-11-12T06:43:03.1840587Z', 'message': {'role': 'assistant', 'content': '', 'tool_calls': [{'function': {'name': 'db_query_tool', 'arguments': {'query': 'SELECT * FROM Artist LIMIT 10;'}}}]}, 'done_reason': 'stop', 'done': True, 'total_duration': 64303423200, 'load_duration': 60301882200, 'prompt_eval_count': 315, 'prompt_eval_duration': 425595000, 'eval_count': 107, 'eval_duration': 3563192000}, id='run-6a2ab1df-3678-410e-8249-565e55d88c91-0', tool_calls=[{'name': 'db_query_tool', 'args': {'query': 'SELECT * FROM Artist LIMIT 10;'}, 'id': 'c94b4974-8ee3-49f0-8e92-29a0d6c00ed5', 'type': 'tool_call'}], usage_metadata={'input_tokens': 315, 'output_tokens': 107, 'total_tokens': 422})"
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain_core.prompts import ChatPromptTemplate\n",
    "\n",
    "query_check_system = \"\"\"You are a SQL expert with a strong attention to detail.\n",
    "Double check the SQLite query for common mistakes, including:\n",
    "- Using NOT IN with NULL values\n",
    "- Using UNION when UNION ALL should have been used\n",
    "- Using BETWEEN for exclusive ranges\n",
    "- Data type mismatch in predicates\n",
    "- Properly quoting identifiers\n",
    "- Using the correct number of arguments for functions\n",
    "- Casting to the correct data type\n",
    "- Using the proper columns for joins\n",
    "\n",
    "If there are any of the above mistakes, rewrite the query. If there are no mistakes, just reproduce the original query.\n",
    "\n",
    "You will call the appropriate tool to execute the query after running this check.\"\"\"\n",
    "\n",
    "query_check_prompt = ChatPromptTemplate.from_messages(\n",
    "    [(\"system\", query_check_system), (\"placeholder\", \"{messages}\")]\n",
    ")\n",
    "query_check = query_check_prompt | llm.bind_tools(\n",
    "    [db_query_tool], tool_choice=\"required\"\n",
    ")\n",
    "\n",
    "query_check.invoke({\"messages\": [(\"user\", \"SELECT * FROM Artist LIMIT 10;\")]})"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-12T06:43:03.192444Z",
     "start_time": "2024-11-12T06:41:58.873465Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [],
   "source": [
    "from typing import Annotated, Literal\n",
    "from langchain_core.messages import AIMessage\n",
    "from pydantic import BaseModel, Field\n",
    "from typing_extensions import TypedDict\n",
    "from langgraph.graph import END, StateGraph, START\n",
    "from langgraph.graph.message import AnyMessage, add_messages\n",
    "\n",
    "# Define the state for the agent\n",
    "class State(TypedDict):\n",
    "    messages: Annotated[list[AnyMessage], add_messages]\n",
    "\n",
    "\n",
    "# Define a new graph\n",
    "workflow = StateGraph(State)\n",
    "\n",
    "\n",
    "# Add a node for the first tool call\n",
    "def first_tool_call(state: State) -> dict[str, list[AIMessage]]:\n",
    "    return {\n",
    "        \"messages\": [\n",
    "            AIMessage(\n",
    "                content=\"\",\n",
    "                tool_calls=[\n",
    "                    {\n",
    "                        \"name\": \"sql_db_list_tables\",\n",
    "                        \"args\": {},\n",
    "                        \"id\": \"tool_abcd123\",\n",
    "                    }\n",
    "                ],\n",
    "            )\n",
    "        ]\n",
    "    }\n",
    "\n",
    "\n",
    "def model_check_query(state: State) -> dict[str, list[AIMessage]]:\n",
    "    \"\"\"\n",
    "    Use this tool to double-check if your query is correct before executing it.\n",
    "    使用此工具在执行之前仔细检查您的查询是否正确。\n",
    "    \"\"\"\n",
    "    return {\"messages\": [query_check.invoke({\"messages\": [state[\"messages\"][-1]]})]}\n",
    "\n",
    "\n",
    "workflow.add_node(\"first_tool_call\", first_tool_call)\n",
    "\n",
    "# Add nodes for the first two tools\n",
    "workflow.add_node(\n",
    "    \"list_tables_tool\", create_tool_node_with_fallback([list_tables_tool])\n",
    ")\n",
    "workflow.add_node(\"get_schema_tool\", create_tool_node_with_fallback([get_schema_tool]))\n",
    "\n",
    "# Add a node for a model to choose the relevant tables based on the question and available tables\n",
    "model_get_schema = llm.bind_tools(\n",
    "    [get_schema_tool]\n",
    ")\n",
    "workflow.add_node(\n",
    "    \"model_get_schema\",\n",
    "    lambda state: {\n",
    "        \"messages\": [model_get_schema.invoke(state[\"messages\"])],\n",
    "    },\n",
    ")\n",
    "\n",
    "# Describe a tool to represent the end state\n",
    "class SubmitFinalAnswer(BaseModel):\n",
    "    \"\"\"Submit the final answer to the user based on the query results.\"\"\"\n",
    "\n",
    "    final_answer: str = Field(..., description=\"The final answer to the user\")\n",
    "\n",
    "\n",
    "# Add a node for a model to generate a query based on the question and schema\n",
    "query_gen_system = \"\"\"You are a SQL expert with a strong attention to detail.\n",
    "\n",
    "Given an input question, output a syntactically correct SQLite query to run, then look at the results of the query and return the answer.\n",
    "\n",
    "DO NOT call any tool besides SubmitFinalAnswer to submit the final answer.\n",
    "\n",
    "When generating the query:\n",
    "\n",
    "Output the SQL query that answers the input question without a tool call.\n",
    "\n",
    "Unless the user specifies a specific number of examples they wish to obtain, always limit your query to at most 5 results.\n",
    "You can order the results by a relevant column to return the most interesting examples in the database.\n",
    "Never query for all the columns from a specific table, only ask for the relevant columns given the question.\n",
    "\n",
    "If you get an error while executing a query, rewrite the query and try again.\n",
    "\n",
    "If you get an empty result set, you should try to rewrite the query to get a non-empty result set.\n",
    "NEVER make stuff up if you don't have enough information to answer the query... just say you don't have enough information.\n",
    "\n",
    "If you have enough information to answer the input question, simply invoke the appropriate tool to submit the final answer to the user.\n",
    "\n",
    "DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database.\"\"\"\n",
    "query_gen_prompt = ChatPromptTemplate.from_messages(\n",
    "    [(\"system\", query_gen_system), (\"placeholder\", \"{messages}\")]\n",
    ")\n",
    "query_gen = query_gen_prompt | llm.bind_tools(\n",
    "    [SubmitFinalAnswer]\n",
    ")\n",
    "\n",
    "def query_gen_node(state: State):\n",
    "    message = query_gen.invoke(state)\n",
    "\n",
    "    # Sometimes, the LLM will hallucinate and call the wrong tool. We need to catch this and return an error message.\n",
    "    tool_messages = []\n",
    "    if message.tool_calls:\n",
    "        for tc in message.tool_calls:\n",
    "            if tc[\"name\"] != \"SubmitFinalAnswer\":\n",
    "                tool_messages.append(\n",
    "                    ToolMessage(\n",
    "                        content=f\"Error: The wrong tool was called: {tc['name']}. Please fix your mistakes. Remember to only call SubmitFinalAnswer to submit the final answer. Generated queries should be outputted WITHOUT a tool call.\",\n",
    "                        tool_call_id=tc[\"id\"],\n",
    "                    )\n",
    "                )\n",
    "    else:\n",
    "        tool_messages = []\n",
    "    return {\"messages\": [message] + tool_messages}\n",
    "\n",
    "workflow.add_node(\"query_gen\", query_gen_node)\n",
    "\n",
    "# Add a node for the model to check the query before executing it\n",
    "workflow.add_node(\"correct_query\", model_check_query)\n",
    "\n",
    "# Add node for executing the query\n",
    "workflow.add_node(\"execute_query\", create_tool_node_with_fallback([db_query_tool]))\n",
    "\n",
    "# Define a conditional edge to decide whether to continue or end the workflow\n",
    "def should_continue(state: State) -> Literal[END, \"correct_query\", \"query_gen\"]:\n",
    "    messages = state[\"messages\"]\n",
    "    last_message = messages[-1]\n",
    "    # If there is a tool call, then we finish\n",
    "    if getattr(last_message, \"tool_calls\", None):\n",
    "        return END\n",
    "    if last_message.content.startswith(\"Error:\"):\n",
    "        return \"query_gen\"\n",
    "    else:\n",
    "        return \"correct_query\"\n",
    "\n",
    "\n",
    "# Specify the edges between the nodes\n",
    "workflow.add_edge(START, \"first_tool_call\")\n",
    "workflow.add_edge(\"first_tool_call\", \"list_tables_tool\")\n",
    "workflow.add_edge(\"list_tables_tool\", \"model_get_schema\")\n",
    "workflow.add_edge(\"model_get_schema\", \"get_schema_tool\")\n",
    "workflow.add_edge(\"get_schema_tool\", \"query_gen\")\n",
    "workflow.add_conditional_edges(\n",
    "    \"query_gen\",\n",
    "    should_continue,\n",
    ")\n",
    "workflow.add_edge(\"correct_query\", \"execute_query\")\n",
    "workflow.add_edge(\"execute_query\", \"query_gen\")\n",
    "\n",
    "\n",
    "# Compile the workflow into a runnable\n",
    "app = workflow.compile()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-12T06:43:20.619161Z",
     "start_time": "2024-11-12T06:43:20.602704Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "outputs": [
    {
     "data": {
      "image/jpeg": "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",
      "text/plain": "<IPython.core.display.Image object>"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import Image, display\n",
    "from langchain_core.runnables.graph import MermaidDrawMethod\n",
    "\n",
    "display(\n",
    "    Image(\n",
    "        app.get_graph().draw_mermaid_png(\n",
    "            draw_method=MermaidDrawMethod.API,\n",
    "        )\n",
    "    )\n",
    ")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-12T06:44:54.898077Z",
     "start_time": "2024-11-12T06:44:52.805514Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "outputs": [
    {
     "data": {
      "text/plain": "'Based on the provided schema, there is no direct link between employees and invoices which would allow us to determine who made the most sales in 2009. We need additional information or a different approach.'"
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "messages = app.invoke(\n",
    "    {\"messages\": [(\"user\", \"Which sales agent made the most in sales in 2009?\")]}\n",
    ")\n",
    "json_str = messages[\"messages\"][-1].tool_calls[0][\"args\"][\"final_answer\"]\n",
    "json_str"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-12T06:45:13.998650Z",
     "start_time": "2024-11-12T06:45:00.579687Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'first_tool_call': {'messages': [AIMessage(content='', additional_kwargs={}, response_metadata={}, id='93deee46-beef-45ec-bbc3-77406017655f', tool_calls=[{'name': 'sql_db_list_tables', 'args': {}, 'id': 'tool_abcd123', 'type': 'tool_call'}])]}}\n",
      "{'list_tables_tool': {'messages': [ToolMessage(content='Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track', name='sql_db_list_tables', id='b3301cea-796d-4120-afe5-71e2e7258f9f', tool_call_id='tool_abcd123')]}}\n",
      "{'model_get_schema': {'messages': [AIMessage(content='The tables listed do not include a sales agent or any direct sales information. We would need a table that links agents to their sales, possibly something like `SalesAgent` or `Sales`. Could you please provide more details about the structure of your database? Specifically, we might need a table that connects sales agents with their sales data for the year 2009.\\n\\nIf you have a specific table name in mind, such as `Sales`, could you please specify it along with any relevant columns like `agent_id` and `sales_amount`? For example, if there\\'s a `Sales` table with an `agent_id` column and a `sale_date` column, we can use that to find out which sales agent made the most in sales in 2009. \\n\\nFor now, let\\'s assume you have a `Sales` table with relevant columns. Could you please provide the name of this table? If not, I will make an educated guess and check if there is a suitable table among the ones listed.\\n<tool_call>\\n{\"name\": \"sql_db_schema\", \"arguments\": \"Sales\"}\\n</tool_call>', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:27.1113122Z', 'message': {'role': 'assistant', 'content': 'The tables listed do not include a sales agent or any direct sales information. We would need a table that links agents to their sales, possibly something like `SalesAgent` or `Sales`. Could you please provide more details about the structure of your database? Specifically, we might need a table that connects sales agents with their sales data for the year 2009.\\n\\nIf you have a specific table name in mind, such as `Sales`, could you please specify it along with any relevant columns like `agent_id` and `sales_amount`? For example, if there\\'s a `Sales` table with an `agent_id` column and a `sale_date` column, we can use that to find out which sales agent made the most in sales in 2009. \\n\\nFor now, let\\'s assume you have a `Sales` table with relevant columns. Could you please provide the name of this table? If not, I will make an educated guess and check if there is a suitable table among the ones listed.\\n<tool_call>\\n{\"name\": \"sql_db_schema\", \"arguments\": \"Sales\"}\\n</tool_call>'}, 'done_reason': 'stop', 'done': True, 'total_duration': 4395021800, 'load_duration': 15752900, 'prompt_eval_count': 301, 'prompt_eval_duration': 348588000, 'eval_count': 227, 'eval_duration': 4022671000}, id='run-59c8b02d-9d1a-4efd-bfe4-b9858aabb7f3-0', usage_metadata={'input_tokens': 301, 'output_tokens': 227, 'total_tokens': 528})]}}\n",
      "{'get_schema_tool': {'messages': []}}\n",
      "{'query_gen': {'messages': [AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:27.6117014Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 493669700, 'load_duration': 11764400, 'prompt_eval_count': 704, 'prompt_eval_duration': 466134000, 'eval_count': 1, 'eval_duration': 18000}, id='run-3af3d9c4-9713-4bdc-9979-841ccef70a5e-0', usage_metadata={'input_tokens': 704, 'output_tokens': 1, 'total_tokens': 705})]}}\n",
      "{'correct_query': {'messages': [AIMessage(content='Please provide the SQLite query that needs to be checked.', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:28.0195214Z', 'message': {'role': 'assistant', 'content': 'Please provide the SQLite query that needs to be checked.'}, 'done_reason': 'stop', 'done': True, 'total_duration': 403779500, 'load_duration': 12206800, 'prompt_eval_count': 301, 'prompt_eval_duration': 191604000, 'eval_count': 12, 'eval_duration': 197055000}, id='run-73e3ef6f-21d2-4258-bc14-4c918c9525d5-0', usage_metadata={'input_tokens': 301, 'output_tokens': 12, 'total_tokens': 313})]}}\n",
      "{'execute_query': {'messages': []}}\n",
      "{'query_gen': {'messages': [AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:28.5253626Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 499324800, 'load_duration': 10980200, 'prompt_eval_count': 716, 'prompt_eval_duration': 464939000, 'eval_count': 1, 'eval_duration': 17000}, id='run-76bbd303-90e5-4f76-adf5-32740252e626-0', usage_metadata={'input_tokens': 716, 'output_tokens': 1, 'total_tokens': 717})]}}\n",
      "{'correct_query': {'messages': [AIMessage(content='Please provide the SQLite query that needs to be checked.', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:28.93028Z', 'message': {'role': 'assistant', 'content': 'Please provide the SQLite query that needs to be checked.'}, 'done_reason': 'stop', 'done': True, 'total_duration': 399876200, 'load_duration': 10529900, 'prompt_eval_count': 301, 'prompt_eval_duration': 190991000, 'eval_count': 12, 'eval_duration': 194946000}, id='run-a372cb13-90f0-4923-8445-92c4a3458c0f-0', usage_metadata={'input_tokens': 301, 'output_tokens': 12, 'total_tokens': 313})]}}\n",
      "{'execute_query': {'messages': []}}\n",
      "{'query_gen': {'messages': [AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:29.4536808Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 517361900, 'load_duration': 11933900, 'prompt_eval_count': 727, 'prompt_eval_duration': 477992000, 'eval_count': 1, 'eval_duration': 17000}, id='run-fd03516b-e564-4b22-9fef-3fbb7c55ee74-0', usage_metadata={'input_tokens': 727, 'output_tokens': 1, 'total_tokens': 728})]}}\n",
      "{'correct_query': {'messages': [AIMessage(content='Please provide the SQLite query that needs to be checked.', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:29.8587204Z', 'message': {'role': 'assistant', 'content': 'Please provide the SQLite query that needs to be checked.'}, 'done_reason': 'stop', 'done': True, 'total_duration': 399993500, 'load_duration': 11868600, 'prompt_eval_count': 301, 'prompt_eval_duration': 191783000, 'eval_count': 12, 'eval_duration': 193301000}, id='run-3450fe62-4399-450e-9be0-5206fe9b7b7b-0', usage_metadata={'input_tokens': 301, 'output_tokens': 12, 'total_tokens': 313})]}}\n",
      "{'execute_query': {'messages': []}}\n",
      "{'query_gen': {'messages': [AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:30.3904227Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 525182600, 'load_duration': 11949100, 'prompt_eval_count': 738, 'prompt_eval_duration': 480525000, 'eval_count': 1, 'eval_duration': 19000}, id='run-33426166-b085-4716-a417-9559b43d51ea-0', usage_metadata={'input_tokens': 738, 'output_tokens': 1, 'total_tokens': 739})]}}\n",
      "{'correct_query': {'messages': [AIMessage(content='Please provide the SQLite query that needs to be checked.', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:30.8136182Z', 'message': {'role': 'assistant', 'content': 'Please provide the SQLite query that needs to be checked.'}, 'done_reason': 'stop', 'done': True, 'total_duration': 418621800, 'load_duration': 25799800, 'prompt_eval_count': 301, 'prompt_eval_duration': 190716000, 'eval_count': 12, 'eval_duration': 198213000}, id='run-df9c8417-cc50-498d-b2b5-cf6b1c1fc14a-0', usage_metadata={'input_tokens': 301, 'output_tokens': 12, 'total_tokens': 313})]}}\n",
      "{'execute_query': {'messages': []}}\n",
      "{'query_gen': {'messages': [AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:31.3549355Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 533161200, 'load_duration': 10910600, 'prompt_eval_count': 749, 'prompt_eval_duration': 483563000, 'eval_count': 1, 'eval_duration': 18000}, id='run-dcc4a30b-360c-42c7-b65b-9db0844b1761-0', usage_metadata={'input_tokens': 749, 'output_tokens': 1, 'total_tokens': 750})]}}\n",
      "{'correct_query': {'messages': [AIMessage(content='Please provide the SQLite query that needs to be checked.', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:31.7619855Z', 'message': {'role': 'assistant', 'content': 'Please provide the SQLite query that needs to be checked.'}, 'done_reason': 'stop', 'done': True, 'total_duration': 401921200, 'load_duration': 11610100, 'prompt_eval_count': 301, 'prompt_eval_duration': 191044000, 'eval_count': 12, 'eval_duration': 195766000}, id='run-7fffb3d4-1b22-4a8a-a615-a95519cdefac-0', usage_metadata={'input_tokens': 301, 'output_tokens': 12, 'total_tokens': 313})]}}\n",
      "{'execute_query': {'messages': []}}\n",
      "{'query_gen': {'messages': [AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:32.3213523Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 551322200, 'load_duration': 12200200, 'prompt_eval_count': 760, 'prompt_eval_duration': 494828000, 'eval_count': 1, 'eval_duration': 17000}, id='run-044d50e5-a479-48c6-82ce-e0f68c282b36-0', usage_metadata={'input_tokens': 760, 'output_tokens': 1, 'total_tokens': 761})]}}\n",
      "{'correct_query': {'messages': [AIMessage(content='Please provide the SQLite query that needs to be checked.', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:32.7294676Z', 'message': {'role': 'assistant', 'content': 'Please provide the SQLite query that needs to be checked.'}, 'done_reason': 'stop', 'done': True, 'total_duration': 402599600, 'load_duration': 11528500, 'prompt_eval_count': 301, 'prompt_eval_duration': 191462000, 'eval_count': 12, 'eval_duration': 196393000}, id='run-85df4343-cb9e-4779-bd16-3eeccc0ef91c-0', usage_metadata={'input_tokens': 301, 'output_tokens': 12, 'total_tokens': 313})]}}\n",
      "{'execute_query': {'messages': []}}\n",
      "{'query_gen': {'messages': [AIMessage(content='', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:33.2983353Z', 'message': {'role': 'assistant', 'content': ''}, 'done_reason': 'stop', 'done': True, 'total_duration': 560820700, 'load_duration': 11867400, 'prompt_eval_count': 771, 'prompt_eval_duration': 498575000, 'eval_count': 1, 'eval_duration': 34000}, id='run-7868caac-0e7d-4b1d-a6d8-95c5d9254023-0', usage_metadata={'input_tokens': 771, 'output_tokens': 1, 'total_tokens': 772})]}}\n",
      "{'correct_query': {'messages': [AIMessage(content='Please provide the SQLite query that needs to be checked.', additional_kwargs={}, response_metadata={'model': 'qwen2.5', 'created_at': '2024-11-12T03:45:33.7081322Z', 'message': {'role': 'assistant', 'content': 'Please provide the SQLite query that needs to be checked.'}, 'done_reason': 'stop', 'done': True, 'total_duration': 403745600, 'load_duration': 11366300, 'prompt_eval_count': 301, 'prompt_eval_duration': 192716000, 'eval_count': 12, 'eval_duration': 196271000}, id='run-24971188-5c19-4d24-8532-f300f411d721-0', usage_metadata={'input_tokens': 301, 'output_tokens': 12, 'total_tokens': 313})]}}\n",
      "{'execute_query': {'messages': []}}\n"
     ]
    },
    {
     "ename": "GraphRecursionError",
     "evalue": "Recursion limit of 25 reached without hitting a stop condition. You can increase the limit by setting the `recursion_limit` config key.\nFor troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/GRAPH_RECURSION_LIMIT",
     "output_type": "error",
     "traceback": [
      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[1;31mGraphRecursionError\u001B[0m                       Traceback (most recent call last)",
      "Cell \u001B[1;32mIn[39], line 1\u001B[0m\n\u001B[1;32m----> 1\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m event \u001B[38;5;129;01min\u001B[39;00m app\u001B[38;5;241m.\u001B[39mstream(\n\u001B[0;32m      2\u001B[0m     {\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mmessages\u001B[39m\u001B[38;5;124m\"\u001B[39m: [(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124muser\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mWhich sales agent made the most in sales in 2009?\u001B[39m\u001B[38;5;124m\"\u001B[39m)]}\n\u001B[0;32m      3\u001B[0m ):\n\u001B[0;32m      4\u001B[0m     \u001B[38;5;28mprint\u001B[39m(event)\n",
      "File \u001B[1;32mD:\\ProgramData\\anaconda3\\envs\\pytorch\\lib\\site-packages\\langgraph\\pregel\\__init__.py:1356\u001B[0m, in \u001B[0;36mPregel.stream\u001B[1;34m(self, input, config, stream_mode, output_keys, interrupt_before, interrupt_after, debug, subgraphs)\u001B[0m\n\u001B[0;32m   1347\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m loop\u001B[38;5;241m.\u001B[39mstatus \u001B[38;5;241m==\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mout_of_steps\u001B[39m\u001B[38;5;124m\"\u001B[39m:\n\u001B[0;32m   1348\u001B[0m     msg \u001B[38;5;241m=\u001B[39m create_error_message(\n\u001B[0;32m   1349\u001B[0m         message\u001B[38;5;241m=\u001B[39m(\n\u001B[0;32m   1350\u001B[0m             \u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mRecursion limit of \u001B[39m\u001B[38;5;132;01m{\u001B[39;00mconfig[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mrecursion_limit\u001B[39m\u001B[38;5;124m'\u001B[39m]\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m reached \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m   1354\u001B[0m         error_code\u001B[38;5;241m=\u001B[39mErrorCode\u001B[38;5;241m.\u001B[39mGRAPH_RECURSION_LIMIT,\n\u001B[0;32m   1355\u001B[0m     )\n\u001B[1;32m-> 1356\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m GraphRecursionError(msg)\n\u001B[0;32m   1357\u001B[0m \u001B[38;5;66;03m# set final channel values as run output\u001B[39;00m\n\u001B[0;32m   1358\u001B[0m run_manager\u001B[38;5;241m.\u001B[39mon_chain_end(loop\u001B[38;5;241m.\u001B[39moutput)\n",
      "\u001B[1;31mGraphRecursionError\u001B[0m: Recursion limit of 25 reached without hitting a stop condition. You can increase the limit by setting the `recursion_limit` config key.\nFor troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/GRAPH_RECURSION_LIMIT"
     ]
    }
   ],
   "source": [
    "for event in app.stream(\n",
    "    {\"messages\": [(\"user\", \"Which sales agent made the most in sales in 2009?\")]}\n",
    "):\n",
    "    print(event)"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "outputs": [
    {
     "data": {
      "text/plain": "'Yes, there is an artist named Accept.'"
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "messages = app.invoke(\n",
    "    {\"messages\": [(\"user\", \"Is there an artist named Accept?\")]}\n",
    ")\n",
    "json_str = messages[\"messages\"][-1].tool_calls[0][\"args\"][\"final_answer\"]\n",
    "json_str"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-12T06:46:44.394406Z",
     "start_time": "2024-11-12T06:46:35.467304Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
